package cn.tedu.baking.exception;


import cn.tedu.baking.commons.response.JsonResult;

import cn.tedu.baking.commons.response.StatusCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * ControllerAdvice注解: 标识当前的类为全局异常处理器类型;可以处理由控制器抛出的异常
 *   1.如果Controller中抛出了异常,首先看是否定义了全局异常处理器;
 *   2.如果定义了会在全局异常处理器中找对应的异常处理方法;
 *   3.如果找到了对应的异常处理方法,则执行异常处理方法中的代码逻辑.
 *
 * RestControllerAdvice注解: 复合注解,相当于 @ResponseBody + @ControllerAdvise注解
 */
//@ControllerAdvice
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    //捕获业务层异常
    @ExceptionHandler
    public JsonResult doHandleServiceException(ServiceException ex){
        log.error(ex.getStatusCode().getMsg());
        return new JsonResult(ex.getStatusCode());
    }
    /*
      ExceptionHandler注解:表示方法为具体的异常处理方法;需要一个异常处理类型的形式参数;
      1.优先查找该控制器异常对应的异常处理方法;
      2.如果没有对应的异常处理方法,则会找父类的异常处理方法;
      3.如果没有父类的异常处理方法,则会走SpringMVC自己的异常处理机制;
     */
    @ExceptionHandler
    public JsonResult doHandleRuntimeException(RuntimeException ex){
        /*
            {"code": 3001, "msg": "请求参数异常", "data": "微博ID值无效"}
         */
        log.error("RuntimeException is: " + ex.getMessage());
        return new JsonResult(StatusCode.VALIDATE_ERROR, ex.getMessage());
    }

    @ExceptionHandler
    public JsonResult doHandleIllegalArgumentException(IllegalArgumentException ex){
        log.error("IllegalArgumentException is: " + ex.getMessage());
        return new JsonResult(StatusCode.VALIDATE_ERROR, ex.getMessage());
    }

    /**
     * 处理由 Spring Validation 框架抛出的异常
     * @param ex 异常处理对象
     * @return JsonResult
     */
    @ExceptionHandler
    public JsonResult doHandleMethodArgumentNotValidException(MethodArgumentNotValidException ex){
        /**
         * Validation框架获取提示消息:ex.getFieldError().getDefaultMessage()
         */
        String message = ex.getFieldError().getDefaultMessage();
        return new JsonResult(StatusCode.VALIDATE_ERROR, message);
    }


    /**
     * Throwable:处理所有的异常;
     *           其他异常处理方法无法处理的异常,都会交由此方法进行处理
     *           一般会在最后,加上此异常处理方法;
     *           一旦加完此方法,控制器中再也没有500状态码.
     * @param ex 异常处理对象
     * @return JsonResult
     */
//    @ExceptionHandler
//    public JsonResult doHandleThrowableException(Throwable ex){
//        return new JsonResult(8888, "Throwable异常!");
//    }
}



















